package com.jiyuren.spring.utils;

import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

/**
 * ClassName: DateUtils<p>
 * Author:jiyuren<p>
 * Fuction: 日期时间类<p>
 * CreateDate:2016 2016/3/22 17:15<p>
 * UpdateUser:<p>
 * UpdateDate:<p>
 */

public class DateUtils {
    private final static ThreadLocal<SimpleDateFormat> dateFormater = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };

    private final static ThreadLocal<SimpleDateFormat> dateFormater2 = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };

    public static String getFillZeroNum(long num) {
        DecimalFormat df = new DecimalFormat("00");
        return df.format(num);
    }

    /**
     * 获取倒计时
     *
     * @param s
     * @return
     */
    public static String getCountTime(long s) {
        long day = s / (3600 * 24);
        long hour = (s - (day * 3600 * 24)) / 3600;
        long minute = (s - (day * 3600 * 24) - hour * 3600) / 60;
        long sc = s - (day * 3600 * 24) - hour * 3600 - minute * 60;
        return getFillZeroNum(hour) + ":" + getFillZeroNum(minute) + ":" + getFillZeroNum(sc);
    }

    /**
     * 根据时间戳获取精确时间
     *
     * @param time 13位
     * @return
     */
    public static String getAccurateTime(long time) {
        Calendar c = Calendar.getInstance();
        c.setTimeInMillis(time);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        return sdf.format(c.getTime());
    }

    /**
     * 根据指定年月份获取月初时间戳
     *
     * @param date
     * @return
     */
    public static long getMonthStartTimeByDate(String date) {
        long time = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        try {
            Date da = sdf.parse(date);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(da);
            time = calendar.getTimeInMillis();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return time;
    }

    /**
     * 根据指定年月份获取月末时间戳
     *
     * @param date
     * @return
     */
    public static long getMonthEndTimeByDate(String date) {
        long time = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        try {
            Date da = sdf.parse(date);
            Calendar calendar = Calendar.getInstance();
            int day = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
            calendar.setTime(da);
            calendar.set(Calendar.DAY_OF_MONTH, day);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            calendar.set(Calendar.MILLISECOND, 99);
            time = calendar.getTimeInMillis();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return time;
    }

    /**
     * 获取当前月开始的时间戳
     *
     * @return
     */
    public static long getMonthStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当前月结束的时间戳
     *
     * @return
     */
    public static long getMonthEndTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int day = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.MILLISECOND, 99);
        return calendar.getTimeInMillis();
    }

    /**
     * 根据时间获取当天开始时间戳
     *
     * @param date
     * @return
     */
    public static long getDayStartTimeByDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * 根据日期获取当天结束时间戳
     *
     * @param date
     * @return
     */
    public static long getDayEndTimeByDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.MILLISECOND, 99);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取今天的开始时间戳
     *
     * @return
     */
    public static long getTodayStartTime() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTimeInMillis();
    }

    /**
     * 获取今天的结束时间戳
     *
     * @return
     */
    public static long getTodayEndTime() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.MILLISECOND, 99);
        return cal.getTimeInMillis();
    }

    private static SimpleDateFormat getSdf(String format) {
        return new SimpleDateFormat(format);
    }

    /**
     * 是否超过当前时间
     * @param date
     * @param format
     * @return
     */
    public static boolean isOverCurr(String date, String format) {
        boolean isThanCurr = false;
        SimpleDateFormat sdf = getSdf(format);
        try {
            Date mDate = sdf.parse(date);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(mDate);
            long mTime = calendar.getTimeInMillis();
            long nowTime = System.currentTimeMillis();
            isThanCurr = mTime > nowTime;

        } catch (ParseException e) {
            e.printStackTrace();
        }
        return isThanCurr;
    }


    /**
     * Get the Dates between Start Date and End Date.
     * 获取两个日期之间的所有日期集合
     *
     * @param startC Start Date
     * @param endC   End Date
     * @return Dates List
     */
    public static List<Date> getDates(Calendar startC, Calendar endC, boolean isExceptStartDay) {
        List<Date> result = new ArrayList<Date>();
        // 排除开始日期
        if (isExceptStartDay) {
            startC.add(Calendar.DAY_OF_YEAR, 1);
        }
        while (startC.before(endC)) {
            startC.set(Calendar.HOUR_OF_DAY, 0);
            startC.set(Calendar.MINUTE, 0);
            startC.set(Calendar.SECOND, 0);
            startC.set(Calendar.MILLISECOND, 0);
            result.add(startC.getTime());
            startC.add(Calendar.DAY_OF_YEAR, 1);
        }
        return result;
    }

    /**
     * getDate TODO(根据时间戳返回Date类型的日期)
     *
     * @param date
     * @return Date
     */
    public static Date getDate(long date) {
        long nowTime = System.currentTimeMillis();
        int nowTimeLength = String.valueOf(nowTime).length();
        int n = nowTimeLength - String.valueOf(date).length();
        if (n == 0) {
            return new Date(date);
        } else {
            long dates = (long) (date * Math.pow(10, n));
            return new Date(dates);
        }
    }

    /**
     * getMonDayLs TODO(返回月份或者日期集合)
     *
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @param type      0 返回月份集合 1 返回日集合
     * @return List<String>
     */
    public static List<String> getMonDayLs(long startTime, long endTime, int type) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> list = new ArrayList<String>();

        Calendar startC = Calendar.getInstance();
        startC.setTime(getDate(startTime));

        Calendar endC = Calendar.getInstance();
        endC.setTime(getDate(endTime));

        List<Date> dateLs = getDates(startC, endC, false);

        switch (type) {
            case 0:
                for (Date date : dateLs) {
                    String dateStr = sdf.format(date);
                    String[] dates = dateStr.split("-");
                    String tempMon = dates[1];
                    list.add(tempMon);
                }
                list = removeDuplicateList(list);
                break;
            case 1:
                for (Date date : dateLs) {
                    String dateStr = sdf.format(date);
                    String[] dates = dateStr.split("-");
                    list.add(dates[2]);
                }
                break;
        }
        return list;
    }

    /**
     * 将字符串转为日期类型
     *
     * @param sdate
     * @return
     */
    public static Date toDate(String sdate) {
        try {
            return dateFormater.get().parse(sdate);
        } catch (ParseException e) {
            return null;
        }
    }

    public static String getFileTimeName(){
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
        return sdf.format(date);
    }

    public static String getCurrTime() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }

    public static String getCurrTimeMs(){
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:ms");
        return sdf.format(date);
    }

    /**
     * 以友好的方式显示时间
     *
     * @param sdate
     * @return
     */
    public static String friendly_time(String sdate) {
        Date time = null;
        time = toDate(sdate);
        String ftime = "";
        Calendar cal = Calendar.getInstance();

        // 判断是否是同一天
        String curDate = dateFormater2.get().format(cal.getTime());
        String paramDate = dateFormater2.get().format(time);
        if (curDate.equals(paramDate)) {
            int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
            if (hour == 0)
                ftime = Math.max(
                        (cal.getTimeInMillis() - time.getTime()) / 60000, 1)
                        + "分钟前";
            else
                ftime = hour + "小时前";
            return ftime;
        }

        long lt = time.getTime() / 86400000;
        long ct = cal.getTimeInMillis() / 86400000;
        int days = (int) (ct - lt);
        if (days == 0) {
            int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
            if (hour == 0)
                ftime = Math.max(
                        (cal.getTimeInMillis() - time.getTime()) / 60000, 1)
                        + "分钟前";
            else
                ftime = hour + "小时前";
        } else if (days == 1) {
            ftime = "昨天";
        } else if (days == 2) {
            ftime = "前天";
        } else if (days > 2 && days <= 10) {
            ftime = days + "天前";
        } else if (days > 10) {
            ftime = dateFormater2.get().format(time);
        }
        return ftime;
    }

    public static String getCoutDonwTime(long second) {
        if (second <= 0) {
            return "";
        }
        long day = second / (3600 * 24);
        long hour = (second - (day * 3600 * 24)) / 3600;
        long minute = (second - (day * 3600 * 24) - hour * 3600) / 60;
        long sc = second - (day * 3600 * 24) - hour * 3600 - minute * 60;
        StringBuilder sb = new StringBuilder();
        sb.append((day == 0 ? "" : getFillZeroNum(day) + "天 "));
        sb.append((hour == 0 ? "" : getFillZeroNum(hour) + "小时 "));
        sb.append((minute == 0 ? "" : getFillZeroNum(minute) + "分 "));
        sb.append((sc == 0 ? "" : getFillZeroNum(sc) + "秒"));
        return sb.toString();
    }

    public static String getCountDownTime(long second) {
        if (second <= 0) {
            return "";
        }
        long day = second / (3600 * 24);
        long hour = (second - (day * 3600 * 24)) / 3600;
        long minute = (second - (day * 3600 * 24) - hour * 3600) / 60;
        long sc = second - (day * 3600 * 24) - hour * 3600 - minute * 60;
        StringBuilder sb = new StringBuilder();
        sb.append((day == 0 ? "" : getFillZeroNum(day) + "天"));
        sb.append((hour == 0 ? "" : getFillZeroNum(hour) + "时"));
        sb.append((minute == 0 ? "" : getFillZeroNum(minute) + "分"));
        sb.append((sc == 0 ? "00" + "秒" : getFillZeroNum(sc) + "秒"));
        return sb.toString();
    }

    /**
     * 返回带有颜色的倒计时文字
     *
     * @param second
     * @return
     */
    public static Spanned getColorCountDownTime(long second) {
        if (second <= 0) {
            return new SpannableString("");
        }
        long day = second / (3600 * 24);
        long hour = (second - (day * 3600 * 24)) / 3600;
        long minute = (second - (day * 3600 * 24) - hour * 3600) / 60;
        long sc = second - (day * 3600 * 24) - hour * 3600 - minute * 60;
        StringBuilder sb = new StringBuilder();
        sb.append((day == 0 ? "" : getFillZeroNum(day) + "天"));
        sb.append((hour == 0 ? "" : getFillZeroNum(hour) + "时"));
        sb.append((minute == 0 ? "" : getFillZeroNum(minute) + "分"));
        sb.append((sc == 0 ? "00" + "秒" : getFillZeroNum(sc) + "秒"));
        SpannableString sp = new SpannableString(sb.toString());
        String word = sb.toString();
        int tianIndex = word.indexOf("天");
        int shiIndex = word.indexOf("时");
        int fenIndex = word.indexOf("分");
        int miaoIndex = word.indexOf("秒");
        if (tianIndex != -1) {
            sp.setSpan(new ForegroundColorSpan(0xFF17C8B8), 0, tianIndex, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
        }
        if (shiIndex != -1) {
            sp.setSpan(new ForegroundColorSpan(0xFF17C8B8), tianIndex + 1, shiIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        if (fenIndex != -1) {
            sp.setSpan(new ForegroundColorSpan(0xFF17C8B8), shiIndex + 1, fenIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        if (miaoIndex != -1) {
            sp.setSpan(new ForegroundColorSpan(0xFF17C8B8), fenIndex + 1, miaoIndex, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        return sp;
    }


    private static String getColorText(String text) {
        return getColorText("#17C8B8", text);
    }

    private static String getColorText(String color, String text) {
        return "<font color='" + color + "'>" + text + "</font>";
    }

    /**
     * 将字符串日期转换为long类型
     *
     * @param date
     * @return 13位时间戳
     * @throws ParseException
     * @throws Exception
     */
    public static Long strDateToLong(String date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date dt = sdf.parse(date);
            return dt.getTime();
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static int getMin(long second) {
        int min = (int) (second / 1000 / 60L);
        return min;
    }

    public static int getCurrYear() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        return year;
    }

    public static String getHMTime() {
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int min = calendar.get(Calendar.MINUTE);
        return hour + ":" + min;
    }

    /**
     * @param dateTime 2016-05-11 12:23:33
     */
    public static boolean isToday(String dateTime) {
        boolean isToday = false;
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String currDate = dateFormat.format(calendar.getTime());
        try {
            Date date = dateFormat.parse(dateTime);
            String judDate = dateFormat.format(date);
            System.out.println("currDate = " + currDate + "judDate =" + judDate);
            if (currDate.equals(judDate)) {
                isToday = true;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return isToday;
    }

    public static void main(String[] args) {
//        long endTime = strDateToLong("2016-05-11 09:10:00");
//        long alarmTime = strDateToLong("2016-05-11 09:05:00");
//        long alarmTime1 = strDateToLong("2016-05-11 09:06:00");
//        System.out.println("结束时间" + endTime);
//        System.out.println("提醒时间" + alarmTime);
//        System.out.println("提醒时间" + alarmTime1);
//        System.out.println("提醒时间" + getAccurateTime(1463462260449L + 180000L));
//        long warnTime = 1463369954306L - 180000L;
//
//        System.out.println("warnTime " + getAccurateTime(warnTime));
//        System.out.println(getMin(360000));
//
//        System.out.println(getHMTime());

        /***
         * endTime = 14633 69954 306
         时间间隔:180000
         warnTime=14633 68154 306
         */

        String result = "1234567890".substring(5, 8);
        System.out.println(result);

        System.out.println("是否今天" + isToday("2016-06-18 20:12:11"));
    }

    /**
     * Calculate days in month int.
     *
     * @param month the month
     * @return the int
     */
    public static int calculateDaysInMonth(int month) {
        return calculateDaysInMonth(0, month);
    }

    /**
     * Calculate days in month int.
     *
     * @param year  the year
     * @param month the month
     * @return the int
     */
    public static int calculateDaysInMonth(int year, int month) {
        // 添加大小月月份并将其转换为list,方便之后的判断
        String[] bigMonths = {"1", "3", "5", "7", "8", "10", "12"};
        String[] littleMonths = {"4", "6", "9", "11"};
        List<String> bigList = Arrays.asList(bigMonths);
        List<String> littleList = Arrays.asList(littleMonths);
        // 判断大小月及是否闰年,用来确定"日"的数据
        if (bigList.contains(String.valueOf(month))) {
            return 31;
        } else if (littleList.contains(String.valueOf(month))) {
            return 30;
        } else {
            if (year <= 0) {
                return 29;
            }
            // 是否闰年
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                return 29;
            } else {
                return 28;
            }
        }
    }
    /**
     * removeDuplicateList TODO(去除重复的数据)
     *
     * @param list
     * @return List<String>
     */
    public static <E> List<E> removeDuplicateList(List<E> list) {
        Set<E> set = new HashSet<E>();
        List<E> newList = new ArrayList<E>();
        for (Iterator<E> iter = list.iterator(); iter.hasNext(); ) {
            Object element = iter.next();
            if (set.add((E) element))
                newList.add((E) element);
        }
        return newList;
    }


}
